package service;

import model.Major;
import model.Subject;
import utils.DatabaseUtil;
import java.sql.*;
import java.util.*;
import javax.swing.JOptionPane;

public class MajorService {

    // 获取所有专业信息的方法
    public List<Major> getAllMajors() {
        List<Major> majors = new ArrayList<>(); // 创建一个用于存储Major对象的列表
        String sql = "SELECT * FROM majors ORDER BY major_code"; // 定义SQL查询语句，按专业代码排序

        try (Connection conn = DatabaseUtil.getConnection(); // 获取数据库连接
             Statement stmt = conn.createStatement(); // 创建Statement对象
             ResultSet rs = stmt.executeQuery(sql)) { // 执行查询语句，并获取结果集

            while (rs.next()) { // 遍历结果集中的每一行
                Major major = new Major(); // 创建一个新的Major对象
                major.setId(rs.getInt("id")); // 设置Major对象的ID
                major.setMajorCode(rs.getString("major_code")); // 设置专业代码
                major.setMajorName(rs.getString("major_name")); // 设置专业名称
                major.setDescription(rs.getString("description")); // 设置专业描述
                major.setDeptCode(rs.getString("dept_code")); // 设置学院代码
                major.setCreatedAt(rs.getTimestamp("created_at")); // 设置创建时间
                majors.add(major); // 将Major对象添加到列表中
            }
        } catch (SQLException e) { // 捕获SQL异常
            e.printStackTrace(); // 打印异常信息
        }
        return majors; // 返回Major对象列表
    }

    // 创建新专业的方法
    public boolean createMajor(Major major) {
        String sql = "INSERT INTO majors (major_code, major_name, dept_code, created_at) " +
                "VALUES (?, ?, ?, CURRENT_TIMESTAMP)"; // 定义SQL插入语句

        try (Connection conn = DatabaseUtil.getConnection(); // 获取数据库连接
             PreparedStatement pstmt = conn.prepareStatement(sql)) { // 创建PreparedStatement对象

            pstmt.setString(1, major.getMajorCode()); // 设置第一个参数为专业代码
            pstmt.setString(2, major.getMajorName()); // 设置第二个参数为专业名称
            pstmt.setString(3, major.getDeptCode()); // 设置第三个参数为学院代码

            return pstmt.executeUpdate() > 0; // 执行插入操作，并返回是否成功
        } catch (SQLException e) { // 捕获SQL异常
            if (e.getErrorCode() == 1062) { // 如果异常错误码为1062，表示唯一键冲突（即专业代码已存在）
                JOptionPane.showMessageDialog(null, "专业代码已存在！"); // 弹出提示框
            }
            e.printStackTrace(); // 打印异常信息
            return false; // 返回创建失败
        }
    }

    // 更新专业信息的方法
    public boolean updateMajor(Major major) {
        String sql = "UPDATE majors SET major_name = ?, description = ? WHERE major_code = ?"; // 定义SQL更新语句

        try (Connection conn = DatabaseUtil.getConnection(); // 获取数据库连接
             PreparedStatement pstmt = conn.prepareStatement(sql)) { // 创建PreparedStatement对象

            pstmt.setString(1, major.getMajorName()); // 设置第一个参数为专业名称
            pstmt.setString(2, major.getDescription()); // 设置第二个参数为专业描述
            pstmt.setString(3, major.getMajorCode()); // 设置第三个参数为专业代码

            return pstmt.executeUpdate() > 0; // 执行更新操作，并返回是否成功
        } catch (SQLException e) { // 捕获SQL异常
            e.printStackTrace(); // 打印异常信息
            return false; // 返回更新失败
        }
    }

    // 删除专业的方法
    public boolean deleteMajor(String majorCode) {
        // 首先检查是否有班级使用该专业
        String checkSql = "SELECT COUNT(*) FROM classes WHERE major_code = ?"; // 定义SQL检查语句
        String deleteSql = "DELETE FROM majors WHERE major_code = ?"; // 定义SQL删除语句

        try (Connection conn = DatabaseUtil.getConnection()) { // 获取数据库连接

            // 先检查是否有关联的班级
            try (PreparedStatement checkStmt = conn.prepareStatement(checkSql)) { // 创建PreparedStatement对象
                checkStmt.setString(1, majorCode); // 设置检查语句中的参数为专业代码
                ResultSet rs = checkStmt.executeQuery(); // 执行检查语句，并获取结果集
                if (rs.next() && rs.getInt(1) > 0) { // 如果结果集中有数据且计数大于0，表示有班级关联到此专业
                    // 如果有班级使用该专业，返回 false
                    JOptionPane.showMessageDialog(null,
                            "无法删除该专业，因为已有班级关联到此专业。\n请先删除或修改相关班级的专业信息。", // 弹出提示框
                            "删除失败", // 提示框标题
                            JOptionPane.ERROR_MESSAGE); // 提示框类型
                    return false;
                }
            }

            // 如果没有关联的班级，执行删除操作
            try (PreparedStatement deleteStmt = conn.prepareStatement(deleteSql)) { // 创建PreparedStatement对象
                deleteStmt.setString(1, majorCode); // 设置删除语句中的参数为专业代码
                return deleteStmt.executeUpdate() > 0; // 执行删除操作，并返回是否成功
            }
        } catch (SQLException e) { // 捕获SQL异常
            e.printStackTrace(); // 打印异常信息
            return false; // 返回删除失败
        }
    }

    // 获取指定专业的所有课程的方法
    public List<Subject> getMajorCourses(String majorCode) {
        List<Subject> subjects = new ArrayList<>(); // 创建一个用于存储Subject对象的列表
        String sql = "SELECT s.* FROM subjects s " +
                "WHERE s.major_code = ?"; // 定义SQL查询语句

        try (Connection conn = DatabaseUtil.getConnection(); // 获取数据库连接
             PreparedStatement stmt = conn.prepareStatement(sql)) { // 创建PreparedStatement对象

            stmt.setString(1, majorCode); // 设置查询语句中的参数为专业代码
            ResultSet rs = stmt.executeQuery(); // 执行查询语句，并获取结果集

            while (rs.next()) { // 遍历结果集中的每一行
                Subject subject = new Subject(); // 创建一个新的Subject对象
                subject.setId(rs.getInt("id")); // 设置Subject对象的ID
                subject.setSubjectCode(rs.getString("subject_code")); // 设置课程代码
                subject.setSubjectName(rs.getString("subject_name")); // 设置课程名称
                subject.setCredits(rs.getDouble("credits")); // 设置学分
                subject.setHours(rs.getInt("hours")); // 设置学时
                subject.setMajorCode(rs.getString("major_code")); // 设置专业代码
                subject.setCreatedAt(rs.getTimestamp("created_at")); // 设置创建时间
                subjects.add(subject); // 将Subject对象添加到列表中
            }
        } catch (SQLException e) { // 捕获SQL异常
            e.printStackTrace(); // 打印异常信息
        }
        return subjects; // 返回Subject对象列表
    }

    // 根据专业代码获取专业信息的方法
    public Major getMajorByCode(String majorCode) {
        String sql = "SELECT * FROM majors WHERE major_code = ?"; // 定义SQL查询语句

        try (Connection conn = DatabaseUtil.getConnection(); // 获取数据库连接
             PreparedStatement stmt = conn.prepareStatement(sql)) { // 创建PreparedStatement对象

            stmt.setString(1, majorCode); // 设置查询语句中的参数为专业代码
            ResultSet rs = stmt.executeQuery(); // 执行查询语句，并获取结果集

            if (rs.next()) { // 如果结果集中有数据
                return new Major(
                        rs.getInt("id"), // 设置ID
                        rs.getString("major_code"), // 设置专业代码
                        rs.getString("major_name"), // 设置专业名称
                        rs.getString("department"), // 设置学院名称
                        rs.getString("description"), // 设置专业描述
                        rs.getTimestamp("created_at") // 设置创建时间
                );
            }
        } catch (SQLException e) { // 捕获SQL异常
            e.printStackTrace(); // 打印异常信息
        }
        return null; // 如果结果集中没有数据，返回null
    }

    // 将课程分配给指定专业的方法
    public boolean assignCourseToMajor(String majorCode, String subjectCode) {
        String sql = "UPDATE subjects SET major_code = ? WHERE subject_code = ?"; // 定义SQL更新语句

        try (Connection conn = DatabaseUtil.getConnection(); // 获取数据库连接
             PreparedStatement stmt = conn.prepareStatement(sql)) { // 创建PreparedStatement对象

            stmt.setString(1, majorCode); // 设置更新语句中的第一个参数为专业代码
            stmt.setString(2, subjectCode); // 设置更新语句中的第二个参数为课程代码

            return stmt.executeUpdate() > 0; // 执行更新操作，并返回是否成功
        } catch (SQLException e) { // 捕获SQL异常
            e.printStackTrace(); // 打印异常信息
            return false; // 返回更新失败
        }
    }

    // 从指定专业中移除课程的方法
    public boolean removeCourseFromMajor(String majorCode, String subjectCode) {
        String sql = "UPDATE subjects SET major_code = NULL WHERE major_code = ? AND subject_code = ?"; // 定义SQL更新语句

        try (Connection conn = DatabaseUtil.getConnection(); // 获取数据库连接
             PreparedStatement stmt = conn.prepareStatement(sql)) { // 创建PreparedStatement对象

            stmt.setString(1, majorCode); // 设置更新语句中的第一个参数为专业代码
            stmt.setString(2, subjectCode); // 设置更新语句中的第二个参数为课程代码

            return stmt.executeUpdate() > 0; // 执行更新操作，并返回是否成功
        } catch (SQLException e) { // 捕获SQL异常
            e.printStackTrace(); // 打印异常信息
            return false; // 返回更新失败
        }
    }
}
